'''Author Juan Pablo Gomez

BANKER ALGORITHM 06-04-07 GNU GPL V2.0


Good luck in your homework

Comments in english, interface in spanish... Excuse :)

'''

import sys
	
#Here you can change the number of customers and the number of resource instances 

n_customers = 5
n_resources_class = 3

Banker=()



class customer:

	''' The customer knows how many resources they need. And how many resources are using.... Of course  '''


	def __init__(self,resources_using,resource_max):
		#Max of resources needed
		self.resources_max=resource_max
		# Number of initial resources
		self.resources_using=resources_using
		#How many resources are need for 
		self.requested_resources=[]
		#print "En uso %d maximos  %d" % (self.resources_using[0],self.resources_max[0])

		for i in range(n_resources_class):
			
			self.requested_resources.append(self.resources_max[i]-self.resources_using[i])

			
			if self.resources_using[i]> Banker.total_resources[i]:

				print "Estado inseguro:el cliente necesita funcionar con un minimo de recursos que sobrepasan el total del banco"
				raw_input()
				exit(1)
			
			
			if self.requested_resources[i] > Banker.total_resources[i]:
				print "Estado inseguro:el cliente %d esta solicitando mas del total recursos del disponible" % i
				raw_input()
				exit(1)
				
		


class banker:

	''' The banker class execute the main cicle for resolve customers needes'''

	def __init__(self,n_resources):
		
		self.customer=[]
		self.total_resources=n_resources
		self.available_resources=[]
		


	def check_resources(self):
		#Area necesary resources? 
		for i in range(n_resources_class):

			self.available_resources.append(self.total_resources[i])
			for j in range(n_customers): 
				self.available_resources[i]-=self.customer[j].resources_using[i]
				if self.available_resources[i] < 0:
					print "No hay suficientes recursos minimos para los clientes "
			
	def attend(self):

		while True:
			# Main cicle
			trials = 0
			freed = 0
			a=0
			for  ii in range(n_customers):
				if ii < len(self.customer)-1:
					#Are all customer satisficed?
					trials+=1
					failed = 0
					
					for jj in range(n_resources_class):
					# This customer can be satisficied with full resources?	
						if self.customer[ii].requested_resources[jj] > self.available_resources[jj]: 
							failed = 1
							print "No se satisfizo el cliente numero %d" % ii
							break
					if  failed==0:
						# A new customber has been satisficied
						freed+=1
						for  jj  in range(n_resources_class):
							self.available_resources[jj] += self.customer[ii].resources_using[jj]
						self.customer.pop(ii)

						print "Cliente satisfecho"


			if trials == 0: 
				#No new trials?
				print "El estado es seguro"
				raw_input()
				exit(0)
			if freed == 0 :
				# In this iteration no customer leave the bank :P
				print "El estado es inseguro"
				raw_input()
				exit(1)
				




if __name__=="__main__":
	'''1)First we need ask about resources
		2) Then the customer needes	
		3) Convert the user inputs from strings to numeric
	'''
	customers=[]
	'''We request some parameter for the problem'''
	print "Algoritmo del banquero, procesos: %d" % n_customers 
	print "Numero de recursos: %d"  %n_resources_class
	print "Ingrese el numero de instancias de cada recurso"
	s_n_resources=raw_input()
	string=s_n_resources.split(",")
	n_resources=[]
	for i in range(len(string)):
		n_resources.append(int(string[i]))

	Banker=banker(n_resources)
		

	for i in range(n_customers):
		print "Ingrese la canditad de recursos asignados para el proceso numero %d"  % i
		s_resources_using=raw_input()
		print "Ingrese el maximo de recursos por asignar al proceso numero %d" %i
		s_resource_max=raw_input()
		
		string=s_resource_max.split(",")
		resource_max=[]
		for i in range(len(string)):
			resource_max.append(int(string[i]))	

		# Number of initial resources
		string=s_resources_using.split(",")
		resources_using=[]
		for i in range(len(string)):
			resources_using.append(int(string[i]))	
			
		customers.append(customer(resources_using,resource_max))
		
	Banker.customer=customers		
	Banker.check_resources()		

	Banker.attend() # Attend the costumers

'''
EXAMPLES

1)

SAFE STATE

4 resources
3 customers


RESOURCES

R0 6
R1 4
R2 7
R3 6



USED

P0  	1,2,2,1
P1 	1,0,3,3
P2	1,1,1,0

MAX

P0 	 3,3,2,2
P1	 1,2,3,4
P2	 1,1,5,0

2)

SAFE  STATE

3 resources
5 customers

R1 	10
R2	5
R3 	7

USED 
P0 	0,1,0 
P1	3,0,2
P2	3,0,2
P3	2,1,1
P4	0,0,2

MAX

P0	7,5,3
P1	3,2,2
P2	9,0,2
P3	2,2,2
P4	4,3,3








'''


	
		
		
		
